深度学习--卷积神经网络基础
之前的推送介绍了一些深度学习中一些简单的模型,如线性回归、softmax回归、多层感知机,今天将介绍卷积神经网络的一些基础知识,主要包括互相关运算、卷积层、特征图与感受野、多输入通道与多输出通道以及池化层。
卷积层
卷积神经网络中最常见的是二维卷积层,常用于处理图像数据。在介绍卷积层之前,先介绍一下互相关运算,以二维互相关运算为例。
二维互相关(cross-correlation)运算的输入是一个二维输入数组和一个二维核(kernel)数组,输出也是一个二维数组,其中核数组通常称为卷积核或过滤器(filter)。卷积核的尺寸通常小于输入数组,卷积核在输入数组上滑动,在每个位置上,卷积核与该位置处的输入子数组按元素相乘并求和,得到输出数组中相应位置的元素。例如,
二维卷积层将输入和卷积核做互相关运算,并加上一个标量偏置来得到输出。卷积层的模型参数包括卷积核和标量偏置。
卷积层得名于卷积运算,但卷积层中用到的并非卷积运算而是互相关运算。我们将核数组上下翻转、左右翻转,再与输入数组做互相关运算,这一过程就是卷积运算。由于卷积层的核数组是可学习的,所以使用互相关运算与使用卷积运算并无本质区别。
特征图与感受野
二维卷积层输出的二维数组可以看作是输入在空间维度(宽和高)上某一级的表征,也叫特征图(feature map)。影响元素
以上图为例,输入中阴影部分的四个元素是输出中阴影部分元素的感受野。我们将图中形状为
卷积层的两个超参数
即填充和步幅,它们可以对给定形状的输入和卷积核改变输出形状。
填充(padding):指在输入高和宽的两侧填充元素(通常是0元素),下图在原输入高和宽的两侧分别添加了值为0的元素。
如果原输入的高和宽是
步幅(stride): 每次滑动的行数与列数
当高上步幅为
多输入通道与多输出通道
例如彩色图像在高和宽2个维度外还有RGB(红、绿、蓝)3个颜色通道。这一维称为通道(channel)维。
多输入通道: 卷积层的输入可以包含多个通道,下图展示了一个含2个输入通道的二维互相关计算的例子。
假设输入数据有
多输出通道:
卷积层的输出也可以包含多个通道,设卷积核输入通道数和输出通道数分别为
可以这样理解,一个
二维卷积层经常用于处理图像,与此前的全连接层相比,它主要有两个优势:
全连接层把图像展平成一个向量,在输入图像上相邻的元素可能因为展平操作不再相邻,网络难以捕捉局部信息。而卷积层的设计,天然地具有提取局部信息的能力。
二是卷积层的参数量更少。不考虑偏置的情况下,一个形状为
的卷积核的参数量是 ,与输入图像的宽高无关。例如将一个输入和输出为 和 的卷积层用全连接层连接,那么参数将有 。因此,使用卷积层可以以较少的参数数量来处理更大的图像。
卷积层实现
import torch
import torch.nn as nn
X = torch.rand(4, 2, 3, 5)
print(X.shape)
conv2d = nn.Conv2d(in_channels = 2, out_channels = 3, kernel_size = (3, 5), stride = 1, padding = (1, 2))
Y = conv2d(X) # X是一个四维张量,[batch_size, in_channels, height, width]
print('Y.shape: ', Y.shape) #[4, out_channels, 3 + 1 * 2 - 3 + 1, 5 + 2 * 2 - 5 + 1]
print('weight.shape: ', conv2d.weight.shape) # [out_channels, in_channels, 3, 5]
print('bias.shape: ', conv2d.bias.shape) # [out_channels]
输出:
torch.Size([4, 2, 3, 5])
Y.shape: torch.Size([4, 3, 3, 5])
weight.shape: torch.Size([3, 2, 3, 5])
bias.shape: torch.Size([3])
stride和padding分别指定步幅和填充。
06池化
池化层主要用于缓解卷积层对位置的过度敏感性。同卷积层一样,池化层每次对输入数据的一个固定形状窗口(又称池化窗口)中的元素计算输出,池化层直接计算池化窗口内元素的最大值或者平均值,该运算也分别叫做最大池化或平均池化。下图2 * 2最大池化。
池化窗口形状为
池化层也可以在输入的高和宽两侧填充并调整窗口的移动步幅来改变输出形状。池化层填充和步幅与卷积层填充和步幅的工作机制一样。
在处理多通道输入数据时,池化层对每个输入通道分别池化,但不会像卷积层那样将各通道的结果按通道相加。这意味着池化层的输出通道数与输入通道数相等。
X = torch.arange(32, dtype = torch.float32).view(1, 2, 4, 4)
# MaxPool2d最大池化 AvgPool2d平均池化
pool2d = nn.MaxPool2d(kernel_size = 3, padding = 1, stride=(2, 1))
Y = pool2d(X) # X是一个四维张量,[batch_size, in_channels, height, width]
print(X.shape)
print(Y.shape) # [batch_size, in_channels, (4 + 2 * 1 - 3 + 2) // 2, (4 + 2 * 1 - 3 + 1) / 1]
输出:
torch.Size([1, 2, 4, 4])
torch.Size([1, 2, 2, 4])
如需源码,请后台回复 "卷积神经"。有什么问题,可添加微信 "wxid-3ccc".